"""登录处理和会话管理模块"""

import time
import random
import logging
from typing import Optional, Dict, List
from urllib.parse import urlparse

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.common.keys import Keys


class LoginHandler:
    """登录处理器 - 处理各平台的登录绕过和会话管理"""
    
    def __init__(self, driver: webdriver.Chrome, platform: str = '1688', verbose: bool = False):
        """
        初始化登录处理器
        
        Args:
            driver: Selenium WebDriver实例
            platform: 平台名称 ('1688', 'taobao', 'jd')
            verbose: 是否详细输出
        """
        self.driver = driver
        self.platform = platform
        self.verbose = verbose
        self.logger = self._setup_logger()
        self.session_established = False
        
        # 平台特定配置
        self.platform_configs = {
            '1688': {
                'home_url': 'https://www.1688.com',
                'login_indicators': ['login', '登录', 'signin'],
                'skip_selectors': [
                    '.close', '.skip', '[class*="close"]', '[class*="skip"]',
                    '.login-skip', '.modal-close', '.popup-close', '.dialog-close',
                    '[aria-label="关闭"]', '[title="关闭"]', '.icon-close'
                ],
                'search_selectors': [
                    "input[name='keywords']", "input[placeholder*='搜索']",
                    ".search-input", "#search-input", "[class*='search'] input"
                ],
                'search_button_selectors': [
                    "button[type='submit']", ".search-btn", "[class*='search'] button",
                    "input[type='submit']", ".search-button"
                ]
            },
            'taobao': {
                'home_url': 'https://www.taobao.com',
                'login_indicators': ['login', '登录', 'signin'],
                'skip_selectors': [
                    '.close', '.skip', '[class*="close"]', '[class*="skip"]',
                    '.login-skip', '.modal-close'
                ],
                'search_selectors': [
                    "#q", "input[name='q']", ".search-input", "[class*='search'] input"
                ],
                'search_button_selectors': [
                    ".btn-search", "button[type='submit']", ".search-btn"
                ]
            },
            'jd': {
                'home_url': 'https://www.jd.com',
                'login_indicators': ['login', '登录', 'signin'],
                'skip_selectors': [
                    '.close', '.skip', '[class*="close"]', '[class*="skip"]',
                    '.login-skip', '.modal-close'
                ],
                'search_selectors': [
                    "#key", "input[name='keyword']", ".search-input", "[class*='search'] input"
                ],
                'search_button_selectors': [
                    ".button", "button[type='submit']", ".search-btn"
                ]
            }
        }
    
    def _setup_logger(self) -> logging.Logger:
        """设置日志记录器"""
        logger = logging.getLogger(f"{__name__}.{self.platform}")
        logger.setLevel(logging.INFO if self.verbose else logging.WARNING)
        
        if not logger.handlers:
            handler = logging.StreamHandler()
            formatter = logging.Formatter(
                '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
            )
            handler.setFormatter(formatter)
            logger.addHandler(handler)
        
        return logger
    
    def establish_session(self) -> bool:
        """
        建立会话 - 访问首页并处理可能的登录弹窗
        
        Returns:
            bool: 是否成功建立会话
        """
        try:
            config = self.platform_configs.get(self.platform, self.platform_configs['1688'])
            
            self.logger.info(f"访问{self.platform}首页建立会话")
            self.driver.get(config['home_url'])
            
            # 等待页面加载
            time.sleep(random.uniform(2, 4))
            
            # 检查并处理登录弹窗
            self._handle_login_popup()
            
            # 验证会话是否建立成功
            if self._verify_session():
                self.session_established = True
                self.logger.info("会话建立成功")
                return True
            else:
                self.logger.warning("会话建立失败")
                return False
                
        except Exception as e:
            self.logger.error(f"建立会话时出错: {e}")
            return False
    
    def _handle_login_popup(self) -> bool:
        """
        处理登录弹窗
        
        Returns:
            bool: 是否成功处理登录弹窗
        """
        try:
            config = self.platform_configs.get(self.platform, self.platform_configs['1688'])
            
            # 检查是否有登录相关元素
            login_detected = False
            for indicator in config['login_indicators']:
                if indicator in self.driver.page_source.lower():
                    login_detected = True
                    break
            
            if not login_detected:
                self.logger.info("未检测到登录弹窗")
                return True
            
            self.logger.info("检测到登录相关内容，尝试关闭弹窗")
            
            # 尝试点击关闭按钮
            for selector in config['skip_selectors']:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    for element in elements:
                        if element.is_displayed() and element.is_enabled():
                            element.click()
                            self.logger.info(f"点击关闭按钮: {selector}")
                            time.sleep(1)
                            return True
                except Exception as e:
                    self.logger.debug(f"尝试点击 {selector} 失败: {e}")
                    continue
            
            # 尝试按ESC键关闭弹窗
            try:
                self.driver.find_element(By.TAG_NAME, 'body').send_keys(Keys.ESCAPE)
                self.logger.info("尝试按ESC键关闭弹窗")
                time.sleep(1)
            except:
                pass
            
            return True
            
        except Exception as e:
            self.logger.error(f"处理登录弹窗时出错: {e}")
            return False
    
    def _verify_session(self) -> bool:
        """
        验证会话是否有效
        
        Returns:
            bool: 会话是否有效
        """
        try:
            # 检查当前URL是否为预期的首页
            current_url = self.driver.current_url.lower()
            config = self.platform_configs.get(self.platform, self.platform_configs['1688'])
            expected_domain = urlparse(config['home_url']).netloc
            
            if expected_domain in current_url:
                # 检查是否还在登录页面
                for indicator in config['login_indicators']:
                    if indicator in current_url:
                        return False
                return True
            
            return False
            
        except Exception as e:
            self.logger.error(f"验证会话时出错: {e}")
            return False
    
    def search_from_homepage(self, keyword: str) -> bool:
        """
        从首页搜索框搜索商品
        
        Args:
            keyword: 搜索关键词
            
        Returns:
            bool: 是否成功执行搜索
        """
        try:
            if not self.session_established:
                if not self.establish_session():
                    return False
            
            config = self.platform_configs.get(self.platform, self.platform_configs['1688'])
            
            # 查找搜索框
            search_box = None
            for selector in config['search_selectors']:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    if elements and elements[0].is_displayed():
                        search_box = elements[0]
                        self.logger.info(f"找到搜索框: {selector}")
                        break
                except:
                    continue
            
            if not search_box:
                self.logger.error("未找到搜索框")
                return False
            
            # 清空并输入关键词
            search_box.clear()
            time.sleep(0.5)
            search_box.send_keys(keyword)
            time.sleep(0.5)
            
            self.logger.info(f"输入搜索关键词: {keyword}")
            
            # 查找并点击搜索按钮
            search_clicked = False
            for selector in config['search_button_selectors']:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    for element in elements:
                        if element.is_displayed() and element.is_enabled():
                            element.click()
                            self.logger.info(f"点击搜索按钮: {selector}")
                            search_clicked = True
                            break
                    if search_clicked:
                        break
                except:
                    continue
            
            # 如果没找到搜索按钮，尝试按回车
            if not search_clicked:
                try:
                    search_box.send_keys(Keys.RETURN)
                    self.logger.info("按回车执行搜索")
                    search_clicked = True
                except:
                    pass
            
            if search_clicked:
                # 等待搜索结果页面加载
                time.sleep(3)
                return self._verify_search_success(keyword)
            else:
                self.logger.error("无法执行搜索")
                return False
                
        except Exception as e:
            self.logger.error(f"从首页搜索时出错: {e}")
            return False
    
    def _verify_search_success(self, keyword: str) -> bool:
        """
        验证搜索是否成功
        
        Args:
            keyword: 搜索关键词
            
        Returns:
            bool: 搜索是否成功
        """
        try:
            current_url = self.driver.current_url.lower()
            
            # 检查URL是否包含搜索相关标识
            search_indicators = ['search', 'selloffer', 's.', 'list']
            url_contains_search = any(indicator in current_url for indicator in search_indicators)
            
            if url_contains_search:
                self.logger.info("成功进入搜索结果页")
                return True
            else:
                self.logger.warning(f"搜索后URL异常: {current_url}")
                return False
                
        except Exception as e:
            self.logger.error(f"验证搜索结果时出错: {e}")
            return False
    
    def handle_search_page_login(self) -> bool:
        """
        处理搜索页面的登录要求
        
        Returns:
            bool: 是否成功处理
        """
        try:
            current_url = self.driver.current_url.lower()
            page_source = self.driver.page_source.lower()
            
            # 检查是否需要登录
            login_required = (
                'login' in current_url or 
                any(indicator in page_source for indicator in ['登录', 'signin', 'login'])
            )
            
            if not login_required:
                return True
            
            self.logger.warning("搜索页面要求登录，尝试处理")
            
            # 尝试关闭登录弹窗
            return self._handle_login_popup()
            
        except Exception as e:
            self.logger.error(f"处理搜索页面登录时出错: {e}")
            return False
    
    def get_session_cookies(self) -> List[Dict]:
        """
        获取当前会话的cookies
        
        Returns:
            List[Dict]: cookies列表
        """
        try:
            return self.driver.get_cookies()
        except Exception as e:
            self.logger.error(f"获取cookies时出错: {e}")
            return []
    
    def set_session_cookies(self, cookies: List[Dict]) -> bool:
        """
        设置会话cookies
        
        Args:
            cookies: cookies列表
            
        Returns:
            bool: 是否成功设置
        """
        try:
            for cookie in cookies:
                self.driver.add_cookie(cookie)
            self.logger.info(f"设置了 {len(cookies)} 个cookies")
            return True
        except Exception as e:
            self.logger.error(f"设置cookies时出错: {e}")
            return False
    
    def refresh_session(self) -> bool:
        """
        刷新会话
        
        Returns:
            bool: 是否成功刷新
        """
        try:
            self.session_established = False
            return self.establish_session()
        except Exception as e:
            self.logger.error(f"刷新会话时出错: {e}")
            return False